// defer是延迟执行，defer后面只能带函数调用，
// defer运行会再panic之前 return之后，return之后需要做两件事确定return值,使用ref清除无用函数栈.defer在return之后，ref之前
// 如果是匿名函数定义在函数内部，具名函数如果对具命进行操作则会等待defer运行完成后return最后的值，无具名函数无法利用return时的值复制变量，defer注册函数栈是FILO先注册后执行。
package main

//作用域的问题
//案例1
// var x int = 1

// func fn() int {
// 	x := 100
// 	fmt.Println("fn函数被执行")
// 	defer fn1() //由于函数未具名，此处调用的值和返回值发生了值复制

// 	return x //此时发生值复制defer内部调用的值不是后面return值复制后的值
// }

// func fn1() {
// 	x++	//x优先使用全局，上层函数定义与此值无关，作用域的确定指是在编译进行
// 	fmt.Printf("%v,%p\n", x, &x) //	2,0x209358
// 	fmt.Println("fn1  defer被调用")
// }
// func main() {
// 	a := fn()
// 	fmt.Printf("%v,%p", a, &a) //	100,0xc00000a0b8

// }

// 案例2:匿名函数
// var x int = 1

// func fn() int { //x未被命名
// 	x = 100
// 	fmt.Println("fn函数被执行")
// 	defer func() {
// 		x++
// 		fmt.Printf("%v,%p\n", x, &x) //	101,0xce9358	此时内存地址引用的还是全局的变量，但由于返回值未具名无法调用到
// 		fmt.Println("fn1  defer被调用")
// 	}()
// 	return x //值复制  return的第一步就进行了值复制，在第一阶段就创建了一个新的内存地址放置数据，并且由于是则匿名无法引用
// }

// func main() {
// 	fmt.Printf("%v,%p", x, &x) //	全局x，此时1,0xce9358
// 	fn()                       //值复制  return的第一步就进行了值复制，在
// 	fmt.Printf("%v,%p", x, &x) //	100,0xc00000a0b8
// }

//案例3:匿名函数
// var x int = 1

// func fn() (x int) { //此时x相当于在函数中预先重新定义x，以后此作用域内所有的x都是这个值
// 	x = 100
// 	fmt.Println("fn函数被执行")
// 	fmt.Printf("%v,%p\n", x, &x) //100,0xc00000a0f8
// 	defer func() {               //由于函数具名，此处调用的值可以影响至返回值
// 		x++
// 		fmt.Printf("%v,%p\n", x, &x) //	101,0xc00000a0f8
// 		fmt.Println("fn1  defer被调用")
// 	}()
// 	return x //此时发生值复制
// }

// func main() {
// 	fmt.Printf("%v,%p", x, &x) //1,0xc00000a0f8
// 	a := fn()
// 	fmt.Printf("%v,%p", a, &a) //	101,0xc00000a0f0

// }
